#!/usr/bin/env python
# -*- coding: utf-8 -*-
import paramiko
import time
import threading
import logging

# 配置日志记录
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

# 配置参数
IP_LIST = [
    "192.168.0.100",  # 第一个IP为主车，其余为从车
    "192.168.0.101",
]
USERNAME = 'wheeltec'
PASSWORD = 'dongguan'
MAX_RETRIES = 3  # 最大重试次数
SSH_TIMEOUT = 10  # SSH连接超时时间（秒）
COMMAND_TIMEOUT = 15  # 命令执行超时时间（秒）

# 存储每辆小车的当前状态
ip_status = ["stop"] * len(IP_LIST)

# 控制单辆小车
def control_onecar(carnub: int, carip: str, carcmd: str):
    retries = 0
    while retries < MAX_RETRIES:
        try:
            # 创建SSH客户端
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            logging.info(f"正在尝试连接IP {carip}...")
            ssh.connect(hostname=carip, port=22, username=USERNAME, password=PASSWORD, timeout=SSH_TIMEOUT)
            logging.info(f"成功连接到IP {carip}")

            # 执行命令
            command = None
            if carcmd == 'open' and ip_status[carnub - 1] == "stop":
                if carnub == 1:
                    command = "DISPLAY=:0 bash ~/wheeltec_ros2/src/wheeltec_multi/scripts/leadercar.sh"
                    logging.info(f"向IP {carip} 发送open命令，将执行leadercar.sh脚本")
                else:
                    command = "DISPLAY=:0 bash ~/wheeltec_ros2/src/wheeltec_multi/scripts/slavecar.sh"
                    logging.info(f"向IP {carip} 发送open命令，将执行slavecar.sh脚本")
            elif carcmd == 'stop':
                command = "DISPLAY=:0 bash ~/wheeltec_ros2/src/wheeltec_multi/scripts/killall.sh"
                logging.info(f"向IP {carip} 发送stop命令，将执行killall.sh脚本")
            else:
                logging.warning(f"IP {carip} 无效的命令或状态")
                return

            if command:
                logging.info(f"正在向IP {carip} 发送命令: {command}")
                stdin, stdout, stderr = ssh.exec_command(command, timeout=COMMAND_TIMEOUT)
                exit_status = stdout.channel.recv_exit_status()
                if exit_status == 0:
                    logging.info(f"IP {carip} 命令执行成功")
                    if carcmd == 'open':
                        ip_status[carnub - 1] = "open"
                    elif carcmd == 'stop':
                        ip_status[carnub - 1] = "stop"
                    break
                else:
                    logging.error(f"IP {carip} 命令执行失败: {stderr.read().decode()}")
        except Exception as e:
            logging.error(f"IP {carip} 连接或执行命令时发生错误: {e}")
            retries += 1
            if retries < MAX_RETRIES:
                logging.info(f"IP {carip} 重试中... ({retries}/{MAX_RETRIES})")
                time.sleep(2)  # 重试前等待2秒
            else:
                logging.error(f"IP {carip} 重试 {MAX_RETRIES} 次后仍失败")
        finally:
            ssh.close()
            logging.info(f"已关闭与IP {carip} 的连接")

# 控制所有小车
def control_allcar(carcmd: str):
    threads = []
    for i, ip in enumerate(IP_LIST):
        thread = threading.Thread(target=control_onecar, args=(i + 1, ip, carcmd))
        threads.append(thread)
        thread.start()
    for thread in threads:
        thread.join()

# 打印所有小车状态
def print_allcar_status():
    logging.info("当前所有车辆IP地址及运行状态如下：")
    for i, ip in enumerate(IP_LIST):
        if i == 0:
            logging.info(f"{i + 1}号主车，编号：{i + 1} ip：{ip} 状态：{ip_status[i]}")
        else:
            logging.info(f"{i + 1}号从车，编号：{i + 1} ip：{ip} 状态：{ip_status[i]}")

# 主函数
def main():
    try:
        print_allcar_status()
        makesure = input("1.请确认目前使用的主车ip及从车ip无误，有误请修改IP_LIST变量，并按回车键确认:")
        logging.info("正在初始化中，请稍后......")
        control_allcar("stop")
        print_allcar_status()
        while True:
            logging.info("2.选择你要操作的小车，开启或者结束运行这辆小车的程序")
            thiscarnub = int(input("请输入你要操作的小车编号数字，并按回车键确认（操作所有车开启或关闭程序可输入数字0）:"))
            cmd = str(input("请输入open或者stop开始运行或者结束运行程序,并按回车键确认:"))
            if thiscarnub == 0:
                control_allcar(cmd)
            else:
                if 1 <= thiscarnub <= len(IP_LIST):
                    control_onecar(thiscarnub, IP_LIST[thiscarnub - 1], cmd)
                else:
                    logging.warning("无效的小车编号")
            print_allcar_status()
    except Exception as e:
        logging.error(f"程序运行出错: {e}")
    finally:
        logging.info("程序结束前终止所有程序运行")
        control_allcar("stop")

# 运行主函数
if __name__ == "__main__":
    main()